package task.manager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.List;

import android.os.Environment;
import android.util.Log;

/**
 * Facade for implementing and storing user data.
 * 
 * @author Harrison Saylor, Aaron Mead, Marc Huet, Greg Ruskin
 * @version 2
 */
public class UserDataFacade {
	
	private static UserDataFacade INSTANCE;
	private List<Task> taskList;
	private List<String> categoryList;
	private static String ACTIVEUSER;
	private static String ACTIVECATEGORY;
	private static String ACTIVETASKNAME;
	private int sortMonth;
	private int sortDay;
	private int sortYear;
	private int sortType = 0;
	private static boolean forceLoad;
	
	public static UserDataFacade getInstance(){
		
		if(INSTANCE == null||forceLoad == true){
			INSTANCE = new UserDataFacade();
			forceLoad = false;
		}
		
		return INSTANCE;
		
	}
	
	public UserDataFacade(){
		try {
			loadTaskData();
			loadCatData();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(taskList == null){
			taskList = new TaskList();
			
			/*
			 * For testing purposes only!
			 */
			//taskList.add(new Task("Test1", 12, 9, 2012, new Integer(0), new Integer(0)));
			//taskList.add(new Task("Test2", 12, 9, 2012, new Integer(0), new Integer(0)));
			//taskList.add(new Task("Test3", 12, 9, 2012, new Integer(0), new Integer(0)));
			/*
			 * End test code.
			 */
			
		} // End of if statement.
		
		if(categoryList == null){
			categoryList = new ArrayList<String>();
			categoryList.add("All");
			categoryList.add("+ New\nCategory");
		}
		
	}

	@SuppressWarnings("unchecked")
	private void loadCatData() throws IOException {
		System.out.println("Loading user's category data....");
		ObjectInputStream ois = null;
		try {
			//we are using external storage, so we need to get the location
			//be sure you have the correct privileges 
			System.out.println("For User: " + ACTIVEUSER);
			File file = new File(Environment.getExternalStorageDirectory() + "/"+ ACTIVEUSER + "/categoryList.bin");
			ois = new ObjectInputStream(new FileInputStream(file));
			categoryList = (List<String>)ois.readObject();
		} catch (StreamCorruptedException e) {
			Log.e("APPLICATION FACADE", "Corrupted binary file");
		} catch (FileNotFoundException e) {
			Log.e("APPLICATION FACADE", "Binary File not found");
			System.out.println("Binary File not found");
		} catch (IOException e) {
			Log.e("APPLICATION FACADE", "General IO Error");
		} catch (ClassNotFoundException e) {
			Log.e("APPLICATION FACADE", "Class not found");
		} finally {
			if (ois != null)
				ois.close();
		} // End of try/catch/finally statements.
		
	}
	
	public void saveCatData() throws IOException {
		System.out.println("Saving user's category data....");
		ObjectOutputStream oos = null;
		try {
			File directory = new File(Environment.getExternalStorageDirectory() + "/" + ACTIVEUSER);
			File file = new File(Environment.getExternalStorageDirectory() + "/" + ACTIVEUSER + "/categoryList.bin");
			System.out.println(Environment.getExternalStorageDirectory() + "/" + ACTIVEUSER + "/categoryList.bin");
			
			directory.mkdir();
			file.createNewFile();
			
			System.out.println("File created");
			oos = new ObjectOutputStream(new FileOutputStream(file));
			System.out.println("ObjectOutputStream instantiated");
			oos.writeObject(categoryList);
			System.out.println("users object written to file");
			oos.flush();
			System.out.println("objectOutputStream flushed");
		} catch (IOException e) {
			Log.e("TaskManagerActivity", "Binary file input general error");
			e.printStackTrace();
		} finally {
			if (oos != null) {
				oos.close();
			} // End of if statement.
		} // End of try/catch/finally statements.
	} // End of saveUsers method.

	@SuppressWarnings("unchecked")
	private void loadTaskData() throws IOException {
		System.out.println("Loading user's task data....");
		ObjectInputStream ois = null;
		try {
			//we are using external storage, so we need to get the location
			//be sure you have the correct privileges 
			System.out.println("For User: " + ACTIVEUSER);
			File file = new File(Environment.getExternalStorageDirectory() + "/"+ ACTIVEUSER + "/taskList.bin");
			ois = new ObjectInputStream(new FileInputStream(file));
			taskList = (List<Task>)ois.readObject();
		} catch (StreamCorruptedException e) {
			Log.e("APPLICATION FACADE", "Corrupted binary file");
		} catch (FileNotFoundException e) {
			Log.e("APPLICATION FACADE", "Binary File not found");
			System.out.println("Binary File not found");
		} catch (IOException e) {
			Log.e("APPLICATION FACADE", "General IO Error");
		} catch (ClassNotFoundException e) {
			Log.e("APPLICATION FACADE", "Class not found");
		} finally {
			if (ois != null)
				ois.close();
		} // End of try/catch/finally statements.
		
	}
	
	public void saveTaskData() throws IOException {
		System.out.println("Saving user's task data....");
		ObjectOutputStream oos = null;
		try {
			File directory = new File(Environment.getExternalStorageDirectory() + "/" + ACTIVEUSER);
			File file = new File(Environment.getExternalStorageDirectory() + "/" + ACTIVEUSER + "/taskList.bin");
			System.out.println(Environment.getExternalStorageDirectory() + "/" + ACTIVEUSER + "/taskList.bin");
			
			directory.mkdir();
			file.createNewFile();
			System.out.println("File created");
			oos = new ObjectOutputStream(new FileOutputStream(file));
			System.out.println("ObjectOutputStream instantiated");
			oos.writeObject(taskList);
			System.out.println("users object written to file");
			oos.flush();
			System.out.println("objectOutputStream flushed");
		} catch (IOException e) {
			Log.e("TaskManagerActivity", "Binary file input general error");
			e.printStackTrace();
		} finally {
			if (oos != null) {
				oos.close();
			} // End of if statement.
		} // End of try/catch/finally statements.
	} // End of saveUsers method.

	public static void setActiveUser(String string) {
		ACTIVEUSER = string;
		forceLoad = true;
	}

	public TaskList getTaskList() {
		
		return (TaskList) taskList;
	}

	public void addTask(Task newTask) {
		taskList.add(newTask);
		
	}

	public String getActiveCategory() {
		
		return ACTIVECATEGORY;
	}
	
	public void setActiveCategory(String string) {
		ACTIVECATEGORY = string;
		
	}

	public void addCategory(String catName) {
		categoryList.add(categoryList.size()-1,catName);
		//categoryList.add(catName);
		
	}

	public String[] getCatNames() {
		String [] retArray = new String[categoryList.size()];
		categoryList.toArray(retArray);
		return retArray;
	}

	public Task getActiveTask() {
		
		return ((TaskList)taskList).get(ACTIVETASKNAME);
	}
	
	public String getActiveTaskAddress() {
		Task task = ((TaskList)taskList).get(ACTIVETASKNAME);
		
		return task.getAddress();
		
	}

	public void setActiveTask(String string) {
		ACTIVETASKNAME = string;
		
	}

	public int getSortMonth() {
		return sortMonth;
	}
	
	public void setSortMonth(int month){
		sortMonth = month;
	}

	public int getSortDay() {
		return sortDay;
	}

	public int getSortYear() {
		return sortYear;
	}

	public int getSortType() {
		return sortType;
	}

	public void setSortDate(int year, int monthOfYear, int dayOfMonth) {
		sortYear = year;
		sortMonth = monthOfYear;
		sortDay = dayOfMonth;
		
	}

	public void setSortType(int sortChoice) {
		sortType = sortChoice;
		
	}
}
